package domain

import (
	"context"

	"github.com/lab-online/internal/report/entity"
	"github.com/lab-online/pkg/auth"
	"github.com/lab-online/pkg/mq"
)

type ReportDomain interface {
	SubscribeReport(
		context.Context, auth.AuthEntity, entity.ReportEntity, chan<- []byte,
	) error
	GetReport(auth.AuthEntity, entity.ReportEntity) (entity.ReportEntity, error)
	SearchReport(auth.AuthEntity, entity.ReportEntity) ([]entity.ReportEntity, error)
}

type ReportMessageQueue interface {
	ConsumeContent(context.Context, func(*mq.Delivery)) error
	SubscribeReport(ctx context.Context, reportID uint, body chan<- []byte) error
	PublishReport(entity.ReportEntity) error
}

type ReportRepository interface {
	SaveReport(entity.ReportEntity) (entity.ReportEntity, error)
	GetReportByID(id uint) (entity.ReportEntity, error)
	SearchReport(entity.ReportEntity) ([]entity.ReportEntity, error)
}
type Domain struct {
	mq         ReportMessageQueue
	repository ReportRepository
}

func New(
	repository ReportRepository, messageQueue ReportMessageQueue,
) (ReportDomain, context.CancelFunc) {
	domain := &Domain{messageQueue, repository}

	ctx, cancel := context.WithCancel(context.Background())
	go func(ctx context.Context) {
		if err := domain.mq.ConsumeContent(ctx, domain.contentConsumer); err != nil {
			panic(err)
		}
	}(ctx)

	return domain, cancel
}
